<script setup lang="ts">
/**
 * 文章详情页组件
 * 提供文章内容渲染、阅读工具栏、分享功能等
 */

import { ref, computed, onMounted, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { 
  ArrowLeft, 
  Share2, 
  Star, 
  BookOpen, 
  ZoomIn, 
  ZoomOut, 
  Moon, 
  Sun,
  ExternalLink,
  Copy,
  Download,
  RefreshCw,
  List,
  X
} from 'lucide-vue-next';
import { toast } from 'sonner';
import { fetchArticleContent } from '@/utils/contentFetcher';
import { useRSSStore } from '@/stores/useRSSStore';
import { processImagesInHtml } from '@/utils/imageProxy';
import { articlesApi, dataTransform } from '@/services/api';
import type { Article } from '@/types';

// 路由实例
const route = useRoute();
const router = useRouter();

// RSS Store
const rssStore = useRSSStore();

// 响应式数据
const fontSize = ref(16);
const isDarkMode = ref(false);
const isLoading = ref(true);
const showShareMenu = ref(false);
const readingProgress = ref(0);
const isLoadingFullContent = ref(false);
const hasFullContent = ref(false);
// 目录数据
const tableOfContents = ref([]);
const showTableOfContents = ref(false);

// 计算属性
const articleId = computed(() => route.params.id as string);

const currentArticle = computed(() => {
  return rssStore.articles.find(article => article.id === articleId.value);
});

const currentFeed = computed(() => {
  if (!currentArticle.value) return null;
  return rssStore.feeds.find(feed => feed.id === currentArticle.value?.feedId);
});

const fontSizeClass = computed(() => {
  const sizeMap: Record<number, string> = {
    12: 'text-xs',
    14: 'text-sm',
    16: 'text-base',
    18: 'text-lg',
    20: 'text-xl',
    24: 'text-2xl',
  };
  return sizeMap[fontSize.value] || 'text-base';
});

/**
 * 处理后的文章内容（包含图片代理）
 */
const processedContent = computed(() => {
  if (!currentArticle.value?.content) return '';
  
  // 处理图片代理
  let content = processImagesInHtml(currentArticle.value.content);
  
  // 生成目录并为标题添加ID
  const headings = [];
  let headingCounter = 0;
  
  content = content.replace(/<(h[1-4])([^>]*)>(.*?)<\/h[1-4]>/gi, (match, tag, attrs, text) => {
    const level = parseInt(tag.charAt(1));
    headingCounter++;
    const cleanText = text.replace(/<[^>]*>/g, ''); // 移除HTML标签
    
    // 检查是否已经有id属性
    const existingIdMatch = attrs.match(/\bid=["']([^"']*)["']/);
    let id;
    
    if (existingIdMatch) {
      // 使用现有的id
      id = existingIdMatch[1];
    } else {
      // 生成新的id
      id = `heading-${headingCounter}`;
      attrs = attrs ? `${attrs} id="${id}"` : ` id="${id}"`;
    }
    
    headings.push({
      id,
      text: cleanText,
      level
    });
    
    // 如果已经有id，保持原样；如果没有，添加新的id
    if (existingIdMatch) {
      return `<${tag}${attrs}>${text}</${tag}>`;
    } else {
      return `<${tag}${attrs}>${text}</${tag}>`;
    }
  });
  
  tableOfContents.value = headings;
  
  return content;
});

/**
 * 返回首页
 */
const goBack = () => {
  router.push('/');
};

/**
 * 增大字体
 */
const increaseFontSize = () => {
  if (fontSize.value < 24) {
    fontSize.value += 2;
  }
};

/**
 * 减小字体
 */
const decreaseFontSize = () => {
  if (fontSize.value > 12) {
    fontSize.value -= 2;
  }
};

/**
 * 切换夜间模式
 */
const toggleDarkMode = () => {
  isDarkMode.value = !isDarkMode.value;
};

/**
 * 切换目录显示
 */
const toggleTableOfContents = () => {
  showTableOfContents.value = !showTableOfContents.value;
};

/**
 * 跳转到指定标题
 */
const scrollToHeading = (headingId: string) => {
  // 等待DOM更新后再查找元素
  setTimeout(() => {
    const element = document.getElementById(headingId);
    if (element) {
      // 计算偏移量，考虑固定头部的高度
      const headerHeight = 100;
      const elementPosition = element.offsetTop - headerHeight;
      
      window.scrollTo({
        top: elementPosition,
        behavior: 'smooth'
      });
      
      showTableOfContents.value = false;
    } else {
      console.warn('未找到目标元素:', headingId);
    }
  }, 100);
};

/**
 * 切换收藏状态
 */
const toggleFavorite = async () => {
  if (!currentArticle.value) return;
  
  try {
    await rssStore.toggleArticleFavorite(currentArticle.value.id);
  } catch (error) {
    console.error('切换收藏状态失败:', error);
  }
};

/**
 * 打开原文链接
 */
const openOriginalLink = () => {
  if (currentArticle.value?.link) {
    window.open(currentArticle.value.link, '_blank');
  }
};

/**
 * 复制文章链接
 */
const copyLink = async () => {
  if (!currentArticle.value?.link) return;
  
  try {
    await navigator.clipboard.writeText(currentArticle.value.link);
    // 这里可以添加toast提示
    console.log('链接已复制到剪贴板');
  } catch (error) {
    console.error('复制链接失败:', error);
  }
  
  showShareMenu.value = false;
};

/**
 * 下载文章
 */
const downloadArticle = () => {
  if (!currentArticle.value) return;
  
  const content = `
# ${currentArticle.value.title}

**作者:** ${currentArticle.value.author || '未知'}
**发布时间:** ${currentArticle.value.publishedAt.toLocaleString()}
**来源:** ${currentFeed.value?.title || '未知'}
**链接:** ${currentArticle.value.link}

---

${currentArticle.value.content || currentArticle.value.summary || '无内容'}
  `;
  
  const blob = new Blob([content], { type: 'text/markdown' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `${currentArticle.value.title}.md`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
  
  showShareMenu.value = false;
};

/**
 * 格式化时间
 * @param {Date} date - 日期对象
 * @returns {string} 格式化后的时间字符串
 */
const formatTime = (date: Date): string => {
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
};

/**
 * 计算阅读进度
 */
const updateReadingProgress = () => {
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
  const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
  const progress = scrollHeight > 0 ? (scrollTop / scrollHeight) * 100 : 0;
  readingProgress.value = Math.min(100, Math.max(0, progress));
};

/**
 * 加载文章完整内容
 */
const loadArticleContent = async () => {
  const id = articleId.value;
  if (!id) {
    router.push('/');
    return;
  }
  
  try {
    isLoading.value = true;
    
    // 首先尝试从后端API获取文章详情
    await loadArticleFromAPI(id);
    
    // 标记文章为已读
    if (currentArticle.value) {
      await rssStore.markArticleAsRead(currentArticle.value.id);
    }
    
    // 如果已经有完整内容，直接返回
    if (hasFullContent.value) {
      return;
    }
    
    // 尝试抓取完整内容
    await loadFullContent();
  } catch (error) {
    console.error('加载文章内容失败:', error);
    toast.error('加载文章内容失败');
  } finally {
    isLoading.value = false;
  }
};

/**
 * 从后端API加载文章详情
 * @param {string} id - 文章ID
 */
const loadArticleFromAPI = async (id: string) => {
  try {
    console.log('🔄 正在从API加载文章详情，ID:', id);
    
    const response = await articlesApi.getArticle(Number(id));
    
    if (response.success && response.data) {
      console.log('✅ 成功获取文章详情:', response.data);
      
      // 转换后端数据为前端格式
      const frontendArticle = dataTransform.backendArticleToFrontend(response.data);
      
      // 更新store中的整个文章对象
      await rssStore.updateOrAddArticle(frontendArticle);
      
      // 检查是否有完整内容
      if (frontendArticle.content && frontendArticle.content.trim() !== '') {
        hasFullContent.value = true;
        console.log('✅ 文章已包含完整内容');
      }
      
      toast.success('文章详情加载完成');
    } else {
      throw new Error(response.message || '获取文章详情失败');
    }
  } catch (error) {
    console.error('❌ 从API加载文章详情失败:', error);
    
    // 如果API调用失败，尝试使用store中的数据
    if (!currentArticle.value) {
      toast.error('文章不存在或已被删除');
      router.push('/');
      return;
    }
    
    console.log('⚠️ 使用store中的文章数据作为备选');
  }
};

/**
 * 抓取文章完整内容
 */
const loadFullContent = async () => {
  if (!currentArticle.value?.link || isLoadingFullContent.value) return;
  
  isLoadingFullContent.value = true;
  
  try {
    toast.info('正在抓取文章完整内容...');
    
    const result = await fetchArticleContent(currentArticle.value.link);
    
    if (result.success && result.content) {
      // 更新文章内容
      currentArticle.value.content = result.content;
      hasFullContent.value = true;
      
      // 更新store中的文章内容
      rssStore.updateArticleContent(currentArticle.value.id, result.content);
      
      toast.success('文章内容加载完成');
      console.log(`成功抓取文章内容，长度: ${result.contentLength}`);
    } else {
      throw new Error(result.error || '抓取失败');
    }
  } catch (error) {
    console.error('抓取文章完整内容失败:', error);
    toast.error(`抓取失败: ${error.message || '未知错误'}`);
    
    // 如果抓取失败，显示原始内容
    if (currentArticle.value && (!currentArticle.value.content || currentArticle.value.content.trim() === '')) {
      currentArticle.value.content = currentArticle.value.summary || '<p>暂无内容</p>';
    }
  } finally {
    isLoadingFullContent.value = false;
  }
};

/**
 * 手动刷新内容
 */
const refreshContent = async () => {
  if (!currentArticle.value?.link) return;
  
  hasFullContent.value = false;
  await loadFullContent();
};

// 监听路由变化
watch(() => route.params.id, () => {
  if (route.params.id) {
    hasFullContent.value = false;
    loadArticleContent();
  }
}, { immediate: true });

// 组件挂载时添加滚动监听
onMounted(() => {
  window.addEventListener('scroll', updateReadingProgress);
  
  // 点击外部关闭分享菜单
  document.addEventListener('click', (e) => {
    const target = e.target as HTMLElement;
    if (!target.closest('.share-menu')) {
      showShareMenu.value = false;
    }
  });
});

// 组件卸载时移除监听器
// onUnmounted(() => {
//   window.removeEventListener('scroll', updateReadingProgress);
// });
</script>

<template>
  <div :class="[
    'min-h-screen transition-colors duration-300',
    isDarkMode 
      ? 'bg-gray-900 text-gray-100' 
      : 'bg-gradient-to-br from-blue-50 via-white to-blue-50 text-gray-900'
  ]">
    <!-- 阅读进度条 -->
    <div class="fixed top-0 left-0 w-full h-1 bg-gray-200 z-50">
      <div 
        class="h-full bg-blue-500 transition-all duration-300 ease-out"
        :style="{ width: `${readingProgress}%` }"
      ></div>
    </div>

    <!-- 顶部导航栏 -->
    <header :class="[
      'sticky top-1 z-40 border-b shadow-sm',
      isDarkMode 
        ? 'bg-gray-800/80 border-gray-700' 
        : 'bg-white/80 border-blue-100'
    ]" class="backdrop-blur-md">
      <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
        <div class="flex items-center justify-between h-16">
          <!-- 返回按钮 -->
          <button
            @click="goBack"
            :class="[
              'flex items-center space-x-2 px-3 py-2 rounded-lg transition-all duration-200',
              isDarkMode
                ? 'text-gray-300 hover:text-white hover:bg-gray-700'
                : 'text-gray-600 hover:text-blue-600 hover:bg-blue-50'
            ]"
          >
            <ArrowLeft class="w-5 h-5" />
            <span>返回</span>
          </button>

          <!-- 文章信息 -->
          <div v-if="currentArticle && !isLoading" class="flex-1 min-w-0 mx-4">
            <h1 class="text-lg font-semibold truncate">
              {{ currentArticle.title }}
            </h1>
            <p :class="[
              'text-sm truncate',
              isDarkMode ? 'text-gray-400' : 'text-gray-500'
            ]">
              {{ currentFeed?.title }} • {{ formatTime(currentArticle.publishedAt) }}
            </p>
          </div>

          <!-- 操作按钮 -->
          <div class="flex items-center space-x-2">
            <!-- 刷新内容按钮 -->
            <button
              v-if="currentArticle"
              @click="refreshContent"
              :disabled="isLoadingFullContent"
              :class="[
                'p-2 rounded-lg transition-all duration-200',
                isLoadingFullContent
                  ? 'text-gray-400 cursor-not-allowed'
                  : isDarkMode
                    ? 'text-gray-400 hover:text-blue-500 hover:bg-gray-700'
                    : 'text-gray-400 hover:text-blue-500 hover:bg-blue-50'
              ]"
              title="刷新完整内容"
            >
              <RefreshCw :class="['w-5 h-5', { 'animate-spin': isLoadingFullContent }]" />
            </button>
            
            <button
              v-if="currentArticle"
              @click="toggleFavorite"
              :class="[
                'p-2 rounded-lg transition-all duration-200',
                currentArticle.isFavorite
                  ? 'text-yellow-500 bg-yellow-50 hover:bg-yellow-100'
                  : isDarkMode
                    ? 'text-gray-400 hover:text-yellow-500 hover:bg-gray-700'
                    : 'text-gray-400 hover:text-yellow-500 hover:bg-yellow-50'
              ]"
              title="收藏"
            >
              <Star :class="['w-5 h-5', { 'fill-current': currentArticle.isFavorite }]" />
            </button>

            <div class="relative share-menu">
              <button
                @click="showShareMenu = !showShareMenu"
                :class="[
                  'p-2 rounded-lg transition-all duration-200',
                  isDarkMode
                    ? 'text-gray-400 hover:text-white hover:bg-gray-700'
                    : 'text-gray-400 hover:text-blue-600 hover:bg-blue-50'
                ]"
                title="分享"
              >
                <Share2 class="w-5 h-5" />
              </button>

              <!-- 分享菜单 -->
              <div v-if="showShareMenu" :class="[
                'absolute right-0 top-12 w-48 rounded-lg shadow-lg border z-50',
                isDarkMode 
                  ? 'bg-gray-800 border-gray-700' 
                  : 'bg-white border-gray-200'
              ]">
                <div class="py-2">
                  <button
                    @click="openOriginalLink"
                    :class="[
                      'w-full text-left px-4 py-2 text-sm flex items-center space-x-2 transition-colors duration-200',
                      isDarkMode
                        ? 'text-gray-300 hover:bg-gray-700'
                        : 'text-gray-700 hover:bg-gray-50'
                    ]"
                  >
                    <ExternalLink class="w-4 h-4" />
                    <span>打开原文</span>
                  </button>
                  
                  <button
                    @click="copyLink"
                    :class="[
                      'w-full text-left px-4 py-2 text-sm flex items-center space-x-2 transition-colors duration-200',
                      isDarkMode
                        ? 'text-gray-300 hover:bg-gray-700'
                        : 'text-gray-700 hover:bg-gray-50'
                    ]"
                  >
                    <Copy class="w-4 h-4" />
                    <span>复制链接</span>
                  </button>
                  
                  <button
                    @click="downloadArticle"
                    :class="[
                      'w-full text-left px-4 py-2 text-sm flex items-center space-x-2 transition-colors duration-200',
                      isDarkMode
                        ? 'text-gray-300 hover:bg-gray-700'
                        : 'text-gray-700 hover:bg-gray-50'
                    ]"
                  >
                    <Download class="w-4 h-4" />
                    <span>下载文章</span>
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </header>

    <!-- 主内容区域 -->
    <main class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
      <!-- 加载状态 -->
      <div v-if="isLoading" class="text-center py-12">
        <div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
        <p :class="['mt-4', isDarkMode ? 'text-gray-400' : 'text-gray-500']">加载文章内容中...</p>
      </div>

      <!-- 文章内容 -->
      <article v-else-if="currentArticle" :class="[
        'prose prose-lg max-w-none transition-all duration-300',
        fontSizeClass,
        isDarkMode ? 'prose-invert' : ''
      ]">
        <!-- 文章头部信息 -->
        <header class="mb-8 pb-6 border-b border-gray-200 dark:border-gray-700">
          <h1 class="text-3xl font-bold mb-4 leading-tight">
            {{ currentArticle.title }}
          </h1>
          
          <div class="flex items-center space-x-4 text-sm text-gray-600 dark:text-gray-400">
            <span v-if="currentArticle.author">
              作者：{{ currentArticle.author }}
            </span>
            
            <span>
              发布时间：{{ formatTime(currentArticle.publishedAt) }}
            </span>
            
            <span v-if="currentFeed">
              来源：{{ currentFeed.title }}
            </span>
          </div>
        </header>

        <!-- 内容状态提示 -->
        <div v-if="isLoadingFullContent" class="bg-yellow-50 dark:bg-yellow-900/20 rounded-lg p-4 mb-6">
          <div class="flex items-center space-x-2">
            <RefreshCw class="w-4 h-4 animate-spin text-yellow-600 dark:text-yellow-400" />
            <span class="text-sm font-medium text-yellow-800 dark:text-yellow-300">正在抓取完整内容...</span>
          </div>
        </div>
        
        <div v-else-if="hasFullContent" class="bg-green-50 dark:bg-green-900/20 rounded-lg p-4 mb-6">
          <div class="flex items-center space-x-2">
            <span class="text-sm font-medium text-green-800 dark:text-green-300">✓ 已加载完整内容</span>
          </div>
        </div>
        
        <!-- 文章摘要 -->
        <div v-if="currentArticle.summary && !hasFullContent" class="bg-blue-50 dark:bg-gray-800 rounded-lg p-4 mb-6">
          <h3 class="text-lg font-semibold mb-2 text-blue-900 dark:text-blue-300">摘要</h3>
          <p class="text-blue-800 dark:text-blue-200">{{ currentArticle.summary }}</p>
        </div>

        <!-- 文章正文 -->
        <div 
          v-if="currentArticle.content"
          v-html="processedContent"
          :class="['article-content', fontSizeClass]"
        ></div>
        
        <!-- 如果没有正文内容，显示摘要 -->
        <div v-else-if="currentArticle.summary" class="text-gray-600 dark:text-gray-400">
          <p>{{ currentArticle.summary }}</p>
          <p class="mt-4">
            <a 
              :href="currentArticle.link" 
              target="_blank" 
              class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"
            >
              查看完整文章 →
            </a>
          </p>
        </div>

        <!-- 相关文章区域 -->
        <div v-if="currentArticle" class="related-articles-section mt-12 pt-8 border-t-2 border-gray-200 dark:border-gray-700">
          <div class="bg-gradient-to-r from-blue-50 to-indigo-50 dark:from-gray-800 dark:to-gray-700 rounded-2xl p-6 shadow-lg border border-blue-100 dark:border-gray-600">
            <div class="flex items-center mb-6">
              <div class="w-1 h-8 bg-gradient-to-b from-blue-500 to-indigo-600 rounded-full mr-4"></div>
              <h3 class="text-xl font-bold text-gray-800 dark:text-gray-200">相关文章</h3>
            </div>
            
            <div class="space-y-4">
              <div class="bg-white dark:bg-gray-800 rounded-xl p-4 shadow-sm border border-gray-100 dark:border-gray-600 hover:shadow-md transition-shadow duration-200">
                <div class="flex items-start space-x-3">
                  <div class="w-2 h-2 bg-blue-500 rounded-full mt-2 flex-shrink-0"></div>
                  <div class="flex-1">
                    <p class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">关键词：奇瑞汽车</p>
                    <div class="space-y-2 text-sm text-gray-600 dark:text-gray-400">
                      <p>奇瑞成立国内业务事业群：下设星途、艾瑞、风云、QQ 四大事业部，李学用兼任总经理</p>
                      <p>奇瑞瑞虎 8 PLUS 乘风版及瑞虎 8L 长虹版 6 月 28 日上市，部分配置升级</p>
                      <p>奇瑞将成为中国首个出口超过 500 万辆的汽车企业</p>
                      <p>奇瑞董事长尹同跃：降价是应对竞争最无奈的招数，是饮鸩止渴的手段</p>
                      <p>奇瑞汽车安全之夜 5 月 13 日举行，五小时连续碰撞实测</p>
                      <p>消息称奇瑞汽车正寻求香港 IPO 筹资约 15 亿美元，没有华尔街银行参与</p>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </article>

      <!-- 文章不存在 -->
      <div v-else class="text-center py-12">
        <div :class="[
          'w-24 h-24 rounded-full flex items-center justify-center mx-auto mb-4',
          isDarkMode ? 'bg-gray-800' : 'bg-gray-100'
        ]">
          <BookOpen :class="['w-12 h-12', isDarkMode ? 'text-gray-600' : 'text-gray-400']" />
        </div>
        <h3 :class="['text-lg font-medium mb-2', isDarkMode ? 'text-gray-200' : 'text-gray-900']">文章不存在</h3>
        <p :class="['mb-6', isDarkMode ? 'text-gray-400' : 'text-gray-500']">请检查文章链接是否正确</p>
        <button
          @click="goBack"
          class="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors duration-200"
        >
          <ArrowLeft class="w-4 h-4 mr-2" />
          返回首页
        </button>
      </div>
    </main>

    <!-- 目录面板 -->
    <div v-if="showTableOfContents && tableOfContents.length > 0" 
         class="fixed inset-0 z-50 flex items-start justify-end pt-20 pr-6"
         @click.self="showTableOfContents = false">
      <div :class="[
        'w-80 max-h-96 overflow-y-auto rounded-2xl shadow-2xl border backdrop-blur-md',
        isDarkMode 
          ? 'bg-gray-800/95 border-gray-700' 
          : 'bg-white/95 border-gray-200'
      ]">
        <div class="p-4">
          <div class="flex items-center justify-between mb-4">
            <h3 :class="['text-lg font-semibold', isDarkMode ? 'text-gray-200' : 'text-gray-800']">目录</h3>
            <button 
              @click="showTableOfContents = false"
              :class="[
                'p-1 rounded-lg transition-colors',
                isDarkMode ? 'hover:bg-gray-700 text-gray-400' : 'hover:bg-gray-100 text-gray-600'
              ]"
            >
              <X class="w-4 h-4" />
            </button>
          </div>
          
          <nav class="space-y-1">
            <button
              v-for="heading in tableOfContents"
              :key="heading.id"
              @click="scrollToHeading(heading.id)"
              :class="[
                'w-full text-left px-3 py-2 rounded-lg transition-all duration-200 text-sm',
                `pl-${(heading.level - 1) * 4 + 3}`,
                isDarkMode
                  ? 'text-gray-300 hover:bg-gray-700 hover:text-white'
                  : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'
              ]"
              :style="{ paddingLeft: `${(heading.level - 1) * 16 + 12}px` }"
            >
              <span class="block truncate">{{ heading.text }}</span>
            </button>
          </nav>
        </div>
      </div>
    </div>

    <!-- 浮动工具栏 -->
    <div class="fixed bottom-6 right-6 z-40">
      <div :class="[
        'flex flex-col space-y-2 p-3 rounded-2xl shadow-lg border backdrop-blur-md',
        isDarkMode 
          ? 'bg-gray-800/80 border-gray-700' 
          : 'bg-white/80 border-gray-200'
      ]">
        <!-- 目录按钮 -->
        <button
          v-if="tableOfContents.length > 0"
          @click="toggleTableOfContents"
          :class="[
            'p-2 rounded-lg transition-all duration-200',
            showTableOfContents
              ? (isDarkMode ? 'bg-blue-600 text-white' : 'bg-blue-600 text-white')
              : (isDarkMode
                  ? 'text-gray-400 hover:text-white hover:bg-gray-700'
                  : 'text-gray-600 hover:text-blue-600 hover:bg-blue-50')
          ]"
          title="目录"
        >
          <List class="w-4 h-4" />
        </button>
        
        <!-- 字体大小控制 -->
        <div class="flex items-center space-x-2">
          <button
            @click="decreaseFontSize"
            :disabled="fontSize <= 12"
            :class="[
              'p-2 rounded-lg transition-all duration-200 disabled:opacity-50',
              isDarkMode
                ? 'text-gray-400 hover:text-white hover:bg-gray-700'
                : 'text-gray-600 hover:text-blue-600 hover:bg-blue-50'
            ]"
            title="减小字体"
          >
            <ZoomOut class="w-4 h-4" />
          </button>
          
          <span :class="['text-sm px-2', isDarkMode ? 'text-gray-300' : 'text-gray-600']">{{ fontSize }}</span>
          
          <button
            @click="increaseFontSize"
            :disabled="fontSize >= 24"
            :class="[
              'p-2 rounded-lg transition-all duration-200 disabled:opacity-50',
              isDarkMode
                ? 'text-gray-400 hover:text-white hover:bg-gray-700'
                : 'text-gray-600 hover:text-blue-600 hover:bg-blue-50'
            ]"
            title="增大字体"
          >
            <ZoomIn class="w-4 h-4" />
          </button>
        </div>

        <!-- 夜间模式切换 -->
        <button
          @click="toggleDarkMode"
          :class="[
            'p-2 rounded-lg transition-all duration-200',
            isDarkMode
              ? 'text-yellow-400 bg-yellow-400/20 hover:bg-yellow-400/30'
              : 'text-gray-600 hover:text-blue-600 hover:bg-blue-50'
          ]"
          :title="isDarkMode ? '切换到日间模式' : '切换到夜间模式'"
        >
          <Sun v-if="isDarkMode" class="w-4 h-4" />
          <Moon v-else class="w-4 h-4" />
        </button>
      </div>
    </div>
  </div>
</template>

<style scoped>
/* 文章内容样式 - 优化版 */
.article-content {
  line-height: 1.75;
  color: #374151;
  font-size: 1.1rem;
  letter-spacing: 0.025em;
}

.dark .article-content {
  color: #e5e7eb;
}

/* 标题样式 - 移除边框，保持简洁 */
.article-content :deep(h1) {
  font-size: 2.25rem;
  font-weight: 700;
  margin-top: 3rem;
  margin-bottom: 1.5rem;
  color: #1f2937;
  line-height: 1.2;
  cursor: pointer;
  scroll-margin-top: 100px;
}

.article-content :deep(h2) {
  font-size: 1.875rem;
  font-weight: 700;
  margin-top: 2.5rem;
  margin-bottom: 1.25rem;
  color: #1f2937;
  line-height: 1.3;
  cursor: pointer;
  scroll-margin-top: 100px;
}

.article-content :deep(h3) {
  font-size: 1.5rem;
  font-weight: 600;
  margin-top: 2rem;
  margin-bottom: 1rem;
  color: #374151;
  cursor: pointer;
  scroll-margin-top: 100px;
}

.article-content :deep(h4) {
  font-size: 1.25rem;
  font-weight: 600;
  margin-top: 1.75rem;
  margin-bottom: 0.875rem;
  color: #4b5563;
  cursor: pointer;
  scroll-margin-top: 100px;
}

.article-content :deep(h5),
.article-content :deep(h6) {
  font-size: 1.125rem;
  font-weight: 600;
  margin-top: 1.5rem;
  margin-bottom: 0.75rem;
  color: #6b7280;
}

.dark .article-content :deep(h1) {
  color: #f9fafb;
}

.dark .article-content :deep(h2) {
  color: #f9fafb;
  background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
  border-color: #0ea5e9;
}

.dark .article-content :deep(h2::before) {
  background: linear-gradient(to bottom, #0ea5e9, #0284c7);
}

.dark .article-content :deep(h3) {
  color: #e5e7eb;
}

.dark .article-content :deep(h4) {
  color: #d1d5db;
}

.dark .article-content :deep(h5),
.dark .article-content :deep(h6) {
  color: #9ca3af;
}

/* 段落样式 */
.article-content :deep(p) {
  margin-bottom: 1.5rem;
  text-align: justify;
  text-justify: inter-ideograph;
}

.article-content :deep(p:first-of-type) {
  font-size: 1.125rem;
  font-weight: 500;
  color: #1f2937;
  margin-bottom: 2rem;
}

.dark .article-content :deep(p:first-of-type) {
  color: #f3f4f6;
}

/* 图片样式 - 更美观 */
.article-content :deep(img) {
  max-width: 100%;
  height: auto;
  border-radius: 12px;
  margin: 2rem auto;
  display: block;
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.article-content :deep(img:hover) {
  transform: scale(1.02);
  box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.15), 0 10px 20px -5px rgba(0, 0, 0, 0.08);
}

.dark .article-content :deep(img) {
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
}

.dark .article-content :deep(img:hover) {
  box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.4), 0 10px 20px -5px rgba(0, 0, 0, 0.3);
}

/* 引用块样式 - 更优雅 */
.article-content :deep(blockquote) {
  position: relative;
  margin: 2rem 0;
  padding: 1.5rem 2rem;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  border-radius: 12px;
  border-left: 5px solid #3b82f6;
  font-style: italic;
  font-size: 1.05rem;
  line-height: 1.7;
  color: #475569;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

.article-content :deep(blockquote::before) {
  content: '"';
  position: absolute;
  top: -0.5rem;
  left: 1rem;
  font-size: 4rem;
  color: #3b82f6;
  opacity: 0.3;
  font-family: Georgia, serif;
}

.dark .article-content :deep(blockquote) {
  background: linear-gradient(135deg, #1f2937 0%, #374151 100%);
  color: #d1d5db;
  border-left-color: #60a5fa;
}

.dark .article-content :deep(blockquote::before) {
  color: #60a5fa;
}

/* 代码样式 - 增强视觉效果 */
.article-content :deep(code) {
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
  color: #92400e;
  padding: 0.375rem 0.625rem;
  border-radius: 8px;
  font-family: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace;
  font-size: 0.9em;
  font-weight: 600;
  border: 2px solid #f59e0b;
  box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1);
  position: relative;
}

.article-content :deep(code::before) {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, #f59e0b, #d97706);
  border-radius: 8px 8px 0 0;
}

.dark .article-content :deep(code) {
  background: linear-gradient(135deg, #451a03 0%, #78350f 100%);
  color: #fbbf24;
  border-color: #f59e0b;
}

.dark .article-content :deep(code::before) {
  background: linear-gradient(90deg, #f59e0b, #d97706);
}

/* 代码块样式 */
.article-content :deep(pre) {
  background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
  color: #e2e8f0;
  padding: 1.5rem;
  border-radius: 12px;
  overflow-x: auto;
  margin: 2rem 0;
  border: 1px solid #475569;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
  position: relative;
}

.article-content :deep(pre::before) {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, #3b82f6, #8b5cf6, #06b6d4);
  border-radius: 12px 12px 0 0;
}

.article-content :deep(pre code) {
  background: none;
  color: inherit;
  padding: 0;
  border: none;
  font-size: 0.875rem;
  line-height: 1.6;
}

.dark .article-content :deep(pre) {
  background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
  border-color: #334155;
}

/* 列表样式 - 每个ul/ol独立计数 */
.article-content :deep(ul),
.article-content :deep(ol) {
  margin: 1.5rem 0;
  padding-left: 0;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
  border-radius: 12px;
  padding: 1.5rem;
  border-left: 4px solid #3b82f6;
  box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

/* 无序列表样式 - 每个ul重置计数器 */
.article-content :deep(ul) {
  list-style: none;
  counter-reset: ul-counter;
}

.article-content :deep(ul li) {
  position: relative;
  padding: 0.75rem 0 0.75rem 3.5rem;
  margin-bottom: 0.5rem;
  line-height: 1.6;
  background: #ffffff;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  transition: all 0.2s ease;
  font-weight: 500;
  counter-increment: ul-counter;
}

.article-content :deep(ul li:hover) {
  background: #dbeafe;
  border-color: #3b82f6;
  transform: translateX(4px);
  box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1);
}

.article-content :deep(ul li::before) {
  content: counter(ul-counter);
  position: absolute;
  left: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  width: 2.25rem;
  height: 2.25rem;
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.875rem;
  font-weight: 700;
  box-shadow: 0 3px 6px -1px rgba(16, 185, 129, 0.3);
  border: 2px solid #ffffff;
}

/* 有序列表样式 - 每个ol重置计数器 */
.article-content :deep(ol) {
  counter-reset: ol-counter;
  list-style: none;
}

.article-content :deep(ol li) {
  position: relative;
  padding: 0.75rem 0 0.75rem 3.5rem;
  margin-bottom: 0.5rem;
  line-height: 1.6;
  counter-increment: ol-counter;
  background: #ffffff;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  transition: all 0.2s ease;
  font-weight: 500;
}

.article-content :deep(ol li:hover) {
  background: #dbeafe;
  border-color: #3b82f6;
  transform: translateX(4px);
  box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1);
}

.article-content :deep(ol li::before) {
  content: counter(ol-counter);
  position: absolute;
  left: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  width: 2.25rem;
  height: 2.25rem;
  background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
  color: white;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.875rem;
  font-weight: 700;
  box-shadow: 0 3px 6px -1px rgba(59, 130, 246, 0.3);
  border: 2px solid #ffffff;
}

/* 暗色模式列表样式 */
.dark .article-content :deep(ul),
.dark .article-content :deep(ol) {
  background: linear-gradient(135deg, #374151 0%, #4b5563 100%);
  border-left-color: #60a5fa;
}

.dark .article-content :deep(ul li),
.dark .article-content :deep(ol li) {
  background: #1f2937;
  border-color: #4b5563;
  color: #e5e7eb;
}

.dark .article-content :deep(ul li:hover),
.dark .article-content :deep(ol li:hover) {
  background: #1e40af;
  border-color: #60a5fa;
  color: #f9fafb;
}

.dark .article-content :deep(ul li::before) {
  background: linear-gradient(135deg, #059669 0%, #047857 100%);
  border-color: #1f2937;
  box-shadow: 0 3px 6px -1px rgba(16, 185, 129, 0.3);
}

.dark .article-content :deep(ol li::before) {
  background: linear-gradient(135deg, #1e40af 0%, #1e3a8a 100%);
  border-color: #1f2937;
  box-shadow: 0 3px 6px -1px rgba(96, 165, 250, 0.3);
}

/* 链接样式 - 更吸引人 */
.article-content :deep(a) {
  color: #3b82f6;
  text-decoration: none;
  font-weight: 500;
  position: relative;
  transition: all 0.3s ease;
}

.article-content :deep(a::after) {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background: linear-gradient(90deg, #3b82f6, #8b5cf6);
  transition: width 0.3s ease;
}

.article-content :deep(a:hover) {
  color: #1d4ed8;
  transform: translateY(-1px);
}

.article-content :deep(a:hover::after) {
  width: 100%;
}

.dark .article-content :deep(a) {
  color: #60a5fa;
}

.dark .article-content :deep(a:hover) {
  color: #93c5fd;
}

/* 表格样式 - 增强背景色和视觉效果 */
.article-content :deep(table) {
  width: 100%;
  border-collapse: collapse;
  margin: 2rem 0;
  background: #ffffff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  border: 2px solid #e2e8f0;
}

.article-content :deep(th),
.article-content :deep(td) {
  padding: 1.25rem 1rem;
  text-align: left;
  border-bottom: 2px solid #e5e7eb;
  position: relative;
}

.article-content :deep(th) {
  background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%);
  font-weight: 700;
  color: #ffffff;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.875rem;
  border-bottom: 2px solid #1e40af;
  position: relative;
  box-shadow: 0 2px 4px -1px rgba(59, 130, 246, 0.3);
}

.article-content :deep(th::after) {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, #60a5fa, #3b82f6, #1e40af);
}

.article-content :deep(td) {
  background: #f8fafc;
  color: #374151;
  font-weight: 500;
  transition: all 0.2s ease;
}

.article-content :deep(tr:nth-child(even) td) {
  background: #f1f5f9;
}

.article-content :deep(tr:hover td) {
  background: #dbeafe;
  transform: scale(1.01);
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.article-content :deep(td:first-child) {
  font-weight: 600;
  color: #1e40af;
  border-left: 4px solid #3b82f6;
}

/* 暗色模式表格样式 */
.dark .article-content :deep(table) {
  background: #1f2937;
  border-color: #374151;
}

.dark .article-content :deep(th) {
  background: linear-gradient(135deg, #1e40af 0%, #1e3a8a 100%);
  color: #f9fafb;
  border-bottom-color: #3b82f6;
  box-shadow: 0 2px 4px -1px rgba(30, 64, 175, 0.4);
}

.dark .article-content :deep(th::after) {
  background: linear-gradient(90deg, #60a5fa, #3b82f6, #1e40af);
}

.dark .article-content :deep(td) {
  background: #374151;
  color: #e5e7eb;
}

.dark .article-content :deep(tr:nth-child(even) td) {
  background: #4b5563;
}

.dark .article-content :deep(tr:hover td) {
  background: #1e40af;
  color: #f9fafb;
}

.dark .article-content :deep(td:first-child) {
  color: #60a5fa;
  border-left-color: #3b82f6;
}

.dark .article-content :deep(th),
.dark .article-content :deep(td) {
  border-bottom-color: #4b5563;
}

/* 分隔线样式 */
.article-content :deep(hr) {
  margin: 3rem 0;
  border: none;
  height: 1px;
  background: linear-gradient(90deg, transparent, #3b82f6, transparent);
}

/* 强调文本 - 增强样式 */
.article-content :deep(strong) {
  font-weight: 700;
  color: #1e40af;
  background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
  padding: 0.125rem 0.375rem;
  border-radius: 4px;
  border: 1px solid #93c5fd;
}

.dark .article-content :deep(strong) {
  color: #60a5fa;
  background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 100%);
  border-color: #3b82f6;
}

.article-content :deep(em) {
  font-style: italic;
  color: #7c3aed;
  background: linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 100%);
  padding: 0.125rem 0.25rem;
  border-radius: 4px;
  font-weight: 500;
}

.dark .article-content :deep(em) {
  color: #a78bfa;
  background: linear-gradient(135deg, #4c1d95 0%, #5b21b6 100%);
}

/* 相关文章区域样式 */
.related-articles-section {
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 2px solid #e5e7eb;
}

.dark .related-articles-section {
  border-top-color: #4b5563;
}

.related-articles-section .bg-gradient-to-r {
  background: linear-gradient(135deg, #f0f9ff 0%, #e0e7ff 100%);
  border: 1px solid #bfdbfe;
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}

.dark .related-articles-section .bg-gradient-to-r {
  background: linear-gradient(135deg, #1f2937 0%, #374151 100%);
  border-color: #4b5563;
}

.related-articles-section h3 {
  font-size: 1.25rem;
  font-weight: 700;
  color: #1e40af;
  margin: 0;
}

.dark .related-articles-section h3 {
  color: #60a5fa;
}

.related-articles-section .bg-white {
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(229, 231, 235, 0.5);
  transition: all 0.3s ease;
}

.dark .related-articles-section .bg-white {
  background: rgba(31, 41, 55, 0.8);
  border-color: rgba(75, 85, 99, 0.5);
}

.related-articles-section .bg-white:hover {
  background: rgba(255, 255, 255, 0.95);
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  transform: translateY(-2px);
}

.dark .related-articles-section .bg-white:hover {
  background: rgba(31, 41, 55, 0.95);
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
}

.related-articles-section p {
  margin: 0;
  line-height: 1.6;
}

.related-articles-section .text-sm {
  font-size: 0.875rem;
}

.related-articles-section .space-y-2 > p {
  margin-bottom: 0.5rem;
  padding: 0.25rem 0;
  border-bottom: 1px solid rgba(229, 231, 235, 0.3);
  transition: color 0.2s ease;
}

.related-articles-section .space-y-2 > p:last-child {
  border-bottom: none;
}

.related-articles-section .space-y-2 > p:hover {
  color: #3b82f6;
  cursor: pointer;
}

.dark .related-articles-section .space-y-2 > p {
  border-bottom-color: rgba(75, 85, 99, 0.3);
}

.dark .related-articles-section .space-y-2 > p:hover {
  color: #60a5fa;
}

/* 响应式优化 */
@media (max-width: 768px) {
  .article-content {
    font-size: 1rem;
  }
  
  .article-content h1 {
    font-size: 1.875rem;
  }
  
  .article-content h2 {
    font-size: 1.5rem;
  }
  
  .article-content h3 {
    font-size: 1.25rem;
  }
  
  .article-content blockquote {
    padding: 1rem 1.5rem;
    margin: 1.5rem 0;
  }
  
  .article-content pre {
    padding: 1rem;
  }
  
  .related-articles-section {
    margin-top: 2rem;
    padding-top: 1.5rem;
  }
  
  .related-articles-section .bg-gradient-to-r {
    padding: 1rem;
  }
  
  .related-articles-section h3 {
    font-size: 1.125rem;
  }
}
</style>"}}]}}